/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = jolt_core.h                                        */
/*  NOTE      =                                                    */
/*  DATE      = 2015/06/02 by songbb                               */
/*******************************************************************/

#ifndef __JOLT_CORE_H_
#define __JOLT_CORE_H_

#include "frlist.h"
#include "frhash2.h"
#include "frstr.h"

#include "conntrack.h"
#include "module.h"
#include "frbyte_buffer.h"

/**
 * Jolt协议通用包头
 */
typedef struct __st_jolt_header
{
    unsigned int ui_version;
    unsigned int ui_length;
    unsigned int ui_msgcode;
    unsigned int ui_session_id;
    unsigned int ui_handler_id;
    unsigned int ui_msg_id;
    unsigned int ui_uncmprsz;
} Jolt_header;

/*
 * L7session_jolt 用于存放Jolt私有的session数据，对应L7_session的p_session_private变量
 */
typedef struct __st_L7session_jolt
{
    /* client登录信息 */
    char *p_username;
    char *p_userrole;

    int i_jolti18nflag;
    int i_utf8fix; // TODO: i_utf8fix
    int i_utf8all; // TODO: i_utf8all
    char *p_mbencoding;
} L7session_jolt;

/**
 * 分片的状态
 */
typedef enum __em_fragment_state {
    APM_JOLT_FRAGMENT_INIT,
    APM_JOLT_FRAGMENT_NEED_NEXT_REQ_PACKET,
    APM_JOLT_FRAGMENT_NEED_NEXT_RESP_PACKET
} Jolt_fragment_state;

/**
 * Jolt数据包结构体
 */
typedef struct __st_L7_jolt_packet
{
    Jolt_fragment_state fragment_state;  /* 当前的分片状态 */
    Frbyte_Packet *p_st_packet;         /* 组包完成的数据 */
    unsigned int ui_length;             /* 数据包长度（解压缩前）*/
    unsigned int ui_msgcode;
    unsigned int ui_handler_id;
    unsigned int ui_msg_id;
    unsigned int ui_uncmprsz;
    unsigned int ui_len_to_read;        /* 还需要从下一个payload中读取多少个字节 */
    struct timeval st_timestamp_first;  /* 第一个请求的分片包的时间 */
    struct timeval st_timestamp_last;   /* 最后一个请求的分片包的时间 */
    unsigned long ul_skip_len;
} L7_jolt_packet;

/**
 * Jolt消息数据载体
 */
typedef struct __st_L7_jolt_msg_data
{
    unsigned int ui_type;
    int i_index;
    char c_char;
    short s_short;
    int i_int;
    long long ll_long;
    float f_float;
    double d_double;
    char *p_string;
    unsigned int i_string_len;
    short s_boolean;
} L7_jolt_msg_data;

/**
 * Jolt交易信息
 */
typedef struct __st_L7_jolt_stmt
{
    unsigned int ui_msg_id;
    Frlist_header *p_list_msg_data;
    struct timeval st_req_end_timestamp;
    struct timeval st_resp_start_timestamp;
    unsigned long ul_resp_server_time_us;
} L7_jolt_stmt;

/**
 * Jolt私有结构体
 */
typedef struct __st_L7session_jolt_private
{
    L7session_jolt *p_st_sess;           /* session数据 */
    L7_jolt_stmt *p_st_jolt_stmt;        /* Jolt当前进行中的交易 */
    L7_jolt_packet *p_st_jolt_packet;    /* 当前处理中的Jolt数据包 */
    Frlist_header *p_report_comm;        /* 用于临时存储report的公共部分数据 */
    Frlist_header *p_report_req;         /* 用于临时存储report的请求部分数据 */
    L7_session *p_st_session;            /* 指向父级的L7_session结构体 */
} L7session_jolt_private;

void jolt_core_add_unfinshed_fragmented_packets(L7session_jolt *p_st_sess);

int jolt_detect(Conntrack *p_st_conn
              , Apm_packet *p_st_packet);

int jolt_analyze(Conntrack *p_st_conn
               , Apm_packet *p_st_packet
               , Frhash_header *p_st_hash_report);

int jolt_session_destory(void *p_st_session_private_in);

#endif
